<?php

namespace app\api\controller\v1;

use app\admin\model\SystemConfig;
use app\common\lib\Show;
use app\common\lib\Status;
use app\common\lib\Str;
use app\common\lib\Toutiao;
use app\common\model\MallAccessToken;
use app\common\model\MallAccountLog;
use app\common\model\MallBonus;
use app\common\model\MallGoods;
use app\common\model\MallGoodsSku;
use app\common\model\MallManager;
use app\common\model\MallManagerDoor;
use app\common\model\MallOrder;
use app\common\model\MallPaylog;
use app\common\model\MallSpecsValue;
use app\common\model\MallTags;
use app\common\model\MallUser;
use app\common\model\MallUserBonus;

class Order extends Base
{
    /**
     * 确认订单接口
     * @return \think\response\Json
     * @throws \think\Exception
     */
    public function directToOrder(){

        $id =$this->request->param('id',0,'intval');
        $sku_id =$this->request->param('sku_id',0,'intval');
        $openid =$this->request->param('openid','','trim');
        try{
            $detail =(new MallGoods())->alias('g')
                ->field('g.id,g.title,g.short_title,g.logo,g.tags,g.market_price,g.goods_price,g.stock,m.title as shoptitle,g.islimit,g.limitnum')
                ->join('mall_manager m','m.id=g.manager_id')
                ->where([['g.id','=',$id]])->find();
            $user =(new MallUser())->getBaseByWhereOne([['openid','=',$openid]],'id,mobile');
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if(!$detail){
            return Show::json_show(Status::mini_error,'查询失败');
        }

        $tags =explode(',',$detail['tags']);
        $tagss=[];
        foreach ($tags as $k=>$v){
            $taginfo =(new MallTags())->getBaseById($v,'id,title');
            $tagss[$k]['title'] = !empty($taginfo) ?$taginfo['title']:'';
        }
        $detail['tags'] =$tagss;
        $detail['mobile'] =!empty($user) ?$user['mobile']:'';
        return Show::json_show(Status::mini_normal,'ok',[
            'order'=>$detail
        ]);
    }


    /**
     * 确认订单接口
     * @return \think\response\Json
     * @throws \think\Exception
     */
    public function directToOrderV2(){

        $id =$this->request->param('id',0,'intval');
        $sku_id =$this->request->param('sku_id',0,'intval');
        $openid =$this->request->param('openid','','trim');
        try{
            $detail =(new MallGoods())->alias('g')
                ->field('g.id,manager_id,g.title,g.short_title,g.logo,g.tags,sku.market_price,sku.price as goods_price,sku.stock,g.islimit,g.limitnum,sku.specs_value_ids')
                ->join('mall_goods_sku sku','sku.goods_id=g.id')
                ->where([['g.id','=',$id],['sku.id','=',$sku_id]])->find();
            $user =(new MallUser())->getBaseByWhereOne([['openid','=',$openid]],'id,mobile');
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if(!$detail){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        $manager =(new MallManager())->find($detail['manager_id']);
        $detail['shoptitle'] = !empty($manager) ? $manager['title']:'';
        $detail['option_name'] =$this->getGetSpecsValueIdsAttr($detail['specs_value_ids']);

        $tags =explode(',',$detail['tags']);
        $tagss=[];
        foreach ($tags as $k=>$v){
            $taginfo =(new MallTags())->getBaseById($v,'id,title');
            $tagss[$k]['title'] = !empty($taginfo) ?$taginfo['title']:'';
        }
        $detail['tags'] =$tagss;
        $detail['mobile'] =!empty($user) ?$user['mobile']:'';
        return Show::json_show(Status::mini_normal,'ok',[
            'order'=>$detail
        ]);
    }

    protected function getGetSpecsValueIdsAttr($value){

        if(empty($value)){
            return '默认';
        }
        $ids = explode("-",$value);
        $res= (new MallSpecsValue())->where('id','in',$ids)
            ->select()->toArray();
        $options= '';
        foreach ($res as $k=>$v){
            $options.= $v['title'].' ';
        }
        return $options;
    }

    /**
     * 下单接口
     * @return \think\response\Json
     */
    public function addToOrder(){
        $id =$this->request->param('id',0,'intval');
        $openid =$this->request->param('openid','','trim');
        $goodsnum =$this->request->param('num',1,'intval');
        $mobile =$this->request->param('mobile','','trim');
        $bonus_id =$this->request->param('bonus_id',0,'intval');
        $pay_type =$this->request->param('pay_type',1,'intval');
        if(!preg_match('/^(?:(?:\+|00)86)?1[3-9]\d{9}$/', $mobile)){
            return Show::json_show(Status::mini_error,'手机号格式有误');
        }
        try{
            $userinfo =(new MallUser())->getBaseByWhereOne([['openid','=',$openid]]);
            $detail =(new MallGoods())->getBaseById($id);

        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if(!$userinfo){
            return Show::json_show(Status::mini_error,'下单用户异常');
        }
        $bonusmoney=0;
        if($bonus_id>0){
            $bonus =(new MallBonus())->getBaseById($bonus_id);
            if(!$bonus){
                return Show::json_show(Status::mini_error,'红包异常');
            }
            $bonusmoney =$bonus['money'];
        }

        if(!$detail){
            return Show::json_show(Status::mini_error,'购买商品已下架，请联系商家');
        }

        if($detail['stock']<$goodsnum){
            return Show::json_show(Status::mini_error,'库存不足');
        }
        // 限购
        if($detail['islimit'] ==1){
            // 单日不限购
            $ordercount=(new MallOrder())->where([['openid','=',$openid],['goods_id','=',$detail['id']],['status','in',[0,1,2,3]]])->count();
            if($detail['perlimitnum'] ==0){
                if($detail['limitnum']<($ordercount+$goodsnum)){
                    return Show::json_show(Status::mini_error,'购买数量超出限购了哦');
                }
            }else{
                $perordercount =(new MallOrder())->where([['openid','=',$openid],['goods_id','=',$detail['id']],['status','in',[0,1,2,3]],['add_date','=',date('Y-m-d')]])->count();
                //file_put_contents('a0099.txt',(new MallOrder())->getLastSql().PHP_EOL,8);
                if($perordercount>=$detail['perlimitnum']){
                    return Show::json_show(Status::mini_error,'单日购买超出限购了哦');
                }
                if($goodsnum>$detail['perlimitnum']){
                    return Show::json_show(Status::mini_error,'单日购买超出限购了哦');
                }
                if($detail['limitnum']<($ordercount+$goodsnum)){
                    return Show::json_show(Status::mini_error,'购买数量超出限购了哦');
                }
            }
        }
        $model =new MallOrder();
        $model->startTrans();
        $data =[
            'openid'=>$openid,
            'manager_id'=>$detail['manager_id'],
            'doors'=>$detail['doors'],
            'goods_title'=>$detail['title'],
            'short_title'=>$detail['short_title'],
            'goods_id'=>$detail['id'],
            'goods_price'=>$detail['goods_price'],
            'market_price'=>$detail['market_price'],
            'cost_price'=>$detail['cost_price'],
            'goods_logo'=>$detail['logo'],
            'tags' =>$detail['tags'],
            'goods_num'=>$goodsnum,
            'orderprice' =>round($detail['goods_price']*$goodsnum,2),
            'payprice' =>round($detail['goods_price']*$goodsnum-$bonusmoney,2),
            'orderno'=>Str::RandomStr(),
            'mobile' =>$mobile,
            'realname'=>$userinfo['nickName'],
            'bonus_id'=>$bonus_id,
            'bonus_price'=>$bonusmoney,
            'pay_type'=>$pay_type,
            'add_date'=>date('Y-m-d'),
            'validity_time' =>$detail['hx_times']
        ];
        try{
            $model->save($data);
            if(!$userinfo['mobile']){
                (new MallUser())->where([['id','=',$userinfo['id']]])->save(['mobile'=>$mobile]);
            }
            // 处理红包已被使用
            if($bonus_id >0){
                (new MallUserBonus())->where([['bonus_id','=',$bonus_id],['openid','=',$openid]])
                    ->save(['used'=>1,'usetime'=>time(),'orderno'=>$data['orderno']]);
            }
        }catch (\Exception $e){
            $model->rollback();
        }
        $model->commit();
        return Show::json_show(Status::mini_normal,'ok',[
            'orderno'=>$data['orderno']
        ]);
    }

    /**
     * 下单接口
     * @return \think\response\Json
     */
    public function addToOrderV2(){
        $id =$this->request->param('id',0,'intval');
        $sku_id =$this->request->param('sku_id',0,'intval');
        $openid =$this->request->param('openid','','trim');
        $goodsnum =$this->request->param('num',1,'intval');
        $mobile =$this->request->param('mobile','','trim');
        $bonus_id =$this->request->param('bonus_id',0,'intval');
        $pay_type =$this->request->param('pay_type',1,'intval');
        if(!preg_match('/^(?:(?:\+|00)86)?1[3-9]\d{9}$/', $mobile)){
            return Show::json_show(Status::mini_error,'手机号格式有误');
        }
        try{
            $userinfo =(new MallUser())->getBaseByWhereOne([['openid','=',$openid]]);
            $detail =(new MallGoods())->getBaseById($id);
            $SKUinfo =(new MallGoodsSku())->getBaseByWhereOne([['goods_id','=',$id],['id','=',$sku_id]]);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if(!$userinfo){
            return Show::json_show(Status::mini_error,'下单用户异常');
        }
        $bonusmoney=0;
        if($bonus_id>0){
            $bonus =(new MallBonus())->getBaseById($bonus_id);
            if(!$bonus){
                return Show::json_show(Status::mini_error,'红包异常');
            }
            $bonusmoney =$bonus['money'];
        }

        if(!$detail){
            return Show::json_show(Status::mini_error,'购买商品已下架，请联系商家');
        }

        if($sku_id>0 && !$SKUinfo){
            return Show::json_show(Status::mini_error,'商品规格异常');
        }

        if($detail['stock']<$goodsnum){
            return Show::json_show(Status::mini_error,'库存不足');
        }
        // 限购
        if($detail['islimit'] ==1){
            // 单日不限购
            $ordercount=(new MallOrder())->where([['openid','=',$openid],['goods_id','=',$detail['id']],['status','in',[0,1,2,3]]])->count();
            if($detail['perlimitnum'] ==0){
                if($detail['limitnum']<($ordercount+$goodsnum)){
                    return Show::json_show(Status::mini_error,'购买数量超出限购了哦');
                }
            }else{
                $perordercount =(new MallOrder())->where([['openid','=',$openid],['goods_id','=',$detail['id']],['status','in',[0,1,2,3]],['add_date','=',date('Y-m-d')]])->count();
                //file_put_contents('a0099.txt',(new MallOrder())->getLastSql().PHP_EOL,8);
                if($perordercount>=$detail['perlimitnum']){
                    return Show::json_show(Status::mini_error,'单日购买超出限购了哦');
                }
                if($goodsnum>$detail['perlimitnum']){
                    return Show::json_show(Status::mini_error,'单日购买超出限购了哦');
                }
                if($detail['limitnum']<($ordercount+$goodsnum)){
                    return Show::json_show(Status::mini_error,'购买数量超出限购了哦');
                }
            }
        }
        $model =new MallOrder();
        $model->startTrans();
        $data =[
            'openid'=>$openid,
            'manager_id'=>$detail['manager_id'],
            'doors'=>$detail['doors'],
            'goods_title'=>$detail['title'],
            'short_title'=>$detail['short_title'],
            'goods_id'=>$detail['id'],
            'specs_value_ids'=>$SKUinfo['specs_value_ids'],
            'goods_price'=>$SKUinfo['price'],
            'market_price'=>$SKUinfo['market_price'],
            'cost_price'=>$SKUinfo['cost_price'],
            'goods_logo'=>$detail['logo'],
            'tags' =>$detail['tags'],
            'goods_num'=>$goodsnum,
            'orderprice' =>round($SKUinfo['price']*$goodsnum,2),
            'payprice' =>round($SKUinfo['price']*$goodsnum-$bonusmoney,2),
            'orderno'=>Str::RandomStr(),
            'mobile' =>$mobile,
            'realname'=>$userinfo['nickName'],
            'bonus_id'=>$bonus_id,
            'bonus_price'=>$bonusmoney,
            'pay_type'=>$pay_type,
            'add_date'=>date('Y-m-d'),
            'validity_time' =>$detail['hx_times']
        ];
        try{
            $model->save($data);
            if(!$userinfo['mobile']){
                (new MallUser())->where([['id','=',$userinfo['id']]])->save(['mobile'=>$mobile]);
            }
            // 处理红包已被使用
            if($bonus_id >0){
                (new MallUserBonus())->where([['bonus_id','=',$bonus_id],['openid','=',$openid]])
                    ->save(['used'=>1,'usetime'=>time(),'orderno'=>$data['orderno']]);
            }
        }catch (\Exception $e){
            $model->rollback();
        }
        $model->commit();
        return Show::json_show(Status::mini_normal,'ok',[
            'orderno'=>$data['orderno']
        ]);
    }

    /**
     * 确认支付订单接口
     * @return \think\response\Json
     * @throws \think\Exception
     */
    public function orderToPay(){
        $orderno =$this->request->param('orderno','','trim');
        try{
            $order =(new MallOrder())->alias('o')
                ->field('o.id,o.goods_title,o.short_title,o.goods_logo,o.tags,o.market_price,o.goods_price,o.goods_num,m.title as shoptitle,o.mobile,o.payprice')
                ->join('mall_manager m','m.id=o.manager_id')
                ->where([['o.orderno','=',$orderno]])
                ->find();
            $config =(new SystemConfig())->where([['name','=','lesstime']])->find();
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }

        $tags =explode(',',$order['tags']);
        $tagss=[];
        if(!empty($tags)){
            foreach ($tags as $k=>$v){
                $taginfo =(new MallTags())->getBaseById($v,'id,title');
                $tagss[$k]['title'] = !empty($taginfo) ?$taginfo['title']:'';
            }
            $order['tags'] =$tagss;
        }
        $order['lesstime'] =intval($config['value']*60+time())*1000;
        return Show::json_show(Status::mini_normal,'ok',[
            'order'=>$order
        ]);
    }


    /**
     * 确认支付订单接口
     * @return \think\response\Json
     * @throws \think\Exception
     */
    public function orderToPayV2(){
        $orderno =$this->request->param('orderno','','trim');
        try{
            $order =(new MallOrder())->alias('o')
                ->field('o.id,o.goods_title,o.short_title,o.specs_value_ids,o.goods_logo,o.tags,o.market_price,o.goods_price,o.goods_num,m.title as shoptitle,o.mobile,o.payprice')
                ->join('mall_manager m','m.id=o.manager_id')
                ->where([['o.orderno','=',$orderno]])
                ->find();
            $config =(new SystemConfig())->where([['name','=','lesstime']])->find();
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }

        $order['option_name'] =$this->getGetSpecsValueIdsAttr($order['specs_value_ids']);


        $tags =explode(',',$order['tags']);
        $tagss=[];
        if(!empty($tags)){
            foreach ($tags as $k=>$v){
                $taginfo =(new MallTags())->getBaseById($v,'id,title');
                $tagss[$k]['title'] = !empty($taginfo) ?$taginfo['title']:'';
            }
            $order['tags'] =$tagss;
        }
        $order['lesstime'] =intval($config['value']*60+time())*1000;
        return Show::json_show(Status::mini_normal,'ok',[
            'order'=>$order
        ]);
    }

    /**
     *  取消订单接口
     * @return \think\response\Json
     */
    public function doStatusOrder()
    {
        $openid = $this->request->param('openid', '', 'trim');
        $order_id = $this->request->param('id', '', 'intval');
        try {
            $orderinfo = (new MallOrder())->getBaseById($order_id);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, '查询失败');
        }
        if (!$orderinfo) {
            return Show::json_show(Status::mini_error, '订单不存在');
        }
        if ($orderinfo['status']==0) {
            (new MallOrder())->where([['id','=',$order_id]])->save(array('status' => 4, 'canceltime' => time()));
        } else {
            return Show::json_show(Status::mini_error, '操作失败');
        }

        return Show::json_show(Status::mini_normal, "操作成功", []);
    }

    /**
     * 订单核销码
     * @return \think\response\Json
     * @throws \think\Exception
     */
    public function orderCode(){
        $order_id =$this->request->param('order_id',0,'intval');
        try {
            $orderinfo = (new MallOrder())->getBaseById($order_id);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, '查询失败');
        }
        if (!$orderinfo) {
            return Show::json_show(Status::mini_error, '订单不存在');
        }
        if ($orderinfo['status'] !=1) {
            return Show::json_show(Status::mini_error, '核销异常');
        }

        try{
            $accessToken =(new MallAccessToken())->find(1);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if(!$accessToken){
            return Show::json_show(Status::mini_error,'系统内部错误');
        }
        if($accessToken['expire_time']<=time()){
            $response= Toutiao::getInstance()->getAccessToken();
            if($response['err_no'] ==0){
                $token =$response['data']['access_token'];
                $accessToken->save(['token'=>$token,'expire_time'=>time()+$response['data']['expires_in']]);
            }else{
                return Show::json_show(Status::mini_error,'系统内部错误');
            }
        }else{
            $token =$accessToken['token'];
        }

        try{
            $path= urlencode("pages/my/my?order_id=".$order_id);
            $result= Toutiao::getInstance()->createQRCode($token,'douyin',$path,'order_'.$order_id);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }

        return Show::json_show(Status::mini_normal,'ok',[
            'code'=>$result
        ]);
    }

    /**
     * 员工核销订单
     * @return void
     */
    public function doHxOrder(){

        $openid =$this->request->param('openid','','trim');
        $order_id =$this->request->param('order_id',0,'intval');

        // 判断核销员权限
        try{
            $user =(new MallUser())->getBaseByWhereOne([['openid','=',$openid]],'id,nickName,ishx,door_id');
            $managerinfo =(new MallManager())->getBaseByWhereOne([['openid','=',$openid],['status','=',1]]);
            $Order =(new MallOrder())->getBaseById($order_id);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if(!$user){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if($Order && $Order['hx_time']>0){
            return Show::json_show(Status::mini_error,'订单已核销，请无重复操作');
        }
        $ishe =0;
        if($managerinfo){
            $manager= (new MallManager())->alias('m')->field('o.*,m.openid as mopenid')
                ->join('mall_order o','o.manager_id=m.id')
                ->where([['o.id','=',$order_id]])->find();
            if($manager){
                $ishe=1;
                $md= (new MallManagerDoor())->where([['manager_id','=',$managerinfo['id']]])->select()->toArray();
                $door_id =$md[0]['id'];
            }
        }

        if($user['ishx'] ==1){
            // 是员工核销
            $manager= (new MallUser())->alias('u')->field('o.*,m.openid as mopenid')
                ->join('mall_manager_door d','d.id=u.door_id')
                ->join('mall_manager m','m.id=d.manager_id')
                ->join('mall_order o','o.manager_id=m.id')
                ->where([['o.id','=',$order_id]])->find();
            if($manager){
               $ishe=1;
               $door_id=$user['door_id'];
            }
        }
        if($ishe==1){
            try{
                // 核销订单
                (new MallOrder())->where([['id','=',$order_id]])->save(['hxuser_id'=>$user['id'],'hx_time'=>time(),'door_id'=>$door_id,'status'=>2]);
                // 向商家发放结算金
                $payprice =round($Order['cost_price']*$Order['goods_num'],2);
                (new MallAccountLog())->save([
                    'mid' =>$user['id'],
                    'openid' =>$manager['mopenid'],
                    'money' =>$payprice,
                    'order_id' =>$order_id,
                    'change_desc'=>'结算金发放',
                    'change_type' =>3
                ]);
                (new MallUser())->where([['openid','=',$manager['mopenid']]])->Inc('balance',$payprice)->update();
                (new MallUser())->where([['openid','=',$manager['mopenid']]])->Inc('income',$payprice)->update();
            }catch (\Exception $e){
                return Show::json_show(Status::mini_error,'查询失败');
            }
        }
        else{
            return Show::json_show(Status::mini_error,'您无核销权限');
        }


        return Show::json_show(Status::mini_normal,'核销成功',[]);
    }

    /**
     * 创建预支付订单
     * @return \think\response\Json
     */
    public function createOrder(){
        $openid =$this->request->param('openid','','trim');
        $ordersn =$this->request->param('ordersn','','trim');

        try{
            $order =(new MallOrder())->getBaseByWhereOne([['openid','=',$openid],['orderno','=',$ordersn]]);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if(!$order){
            return Show::json_show(Status::mini_error,'订单异常，请返回重试');
        }

        try{
            $paylog =(new MallPaylog())->getBaseByWhereOne([['order_id','=',$order['id']],['status','=',0],['type','=',1]]);
        }catch(\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if(!$paylog){
            $paylogdata =[
                'order_id'=>$order['id'],
                'ordersn'=>Str::RandomStr(),
                'type'=>1,
                'status'=>0,
                'money'=>$order['payprice']
            ];
            (new MallPaylog())->save($paylogdata);
        }else{
            $paylogdata =[
                'ordersn'=>Str::RandomStr(),
                'money'=>$order['payprice']
            ];
            (new MallPaylog())->where([['id','=',$paylog['id']]])->save($paylogdata);
        }

        try{
            $data=['orderno'=>$paylogdata['ordersn'],'goods_title'=>$order['goods_title'],'payprice'=>$order['payprice']];
            $response  = Toutiao::getInstance()->create_order($data);
        }catch(\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if($response['err_no'] ==0){
            return Show::json_show(Status::mini_normal,'ok',[
                'response'=>$response['data']
            ]);
        }else{
            return Show::json_show(Status::mini_error,'支付内部错误，请稍后重试');
        }
    }

    /**
     * 处理退款
     * @return \think\response\Json|void
     */
    public function toRefundOrder(){
        $order_id =$this->request->param('id','','intval');
        $openid =$this->request->param('openid','','trim');

        try{
            $order =(new MallOrder())->getBaseByWhereOne([['openid','=',$openid],['id','=',$order_id]]);
            $paylog =(new MallPaylog())->getBaseByWhereOne([['order_id','=',$order_id]]);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if(!$order){
            return Show::json_show(Status::mini_error,'订单不存在');
        }
        if($order['status'] !=1){
            return Show::json_show(Status::mini_error,'订单异常');
        }
        if(!$paylog || ($paylog['status']!=1 && $paylog)){
            return Show::json_show(Status::mini_error,'订单支付异常');
        }
        // 处理退款
        try{
            $data =[
                'ordersn'=>$paylog['ordersn'],
                'out_refund_no'=>Str::RandomStr(),
                'money'=>$paylog['money'],
                'reason'=>'暂时不要了'
            ];
            $response= Toutiao::getInstance()->refund_order($data);
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if(isset($response['err_no']) && $response['err_no'] ==0){
            (new MallOrder())->where([['id','=',$order_id]])->save(['status'=>3]);
            return Show::json_show(Status::mini_normal,'ok',[
            ]);
        }else{
            return Show::json_show(Status::mini_error,'退款失败');
        }
    }

}